﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections.Generic;

namespace SaaS
{
    //Session veriables used
    //"LoginID" - Tenant's login ID
    //"WorkflowMode" = 
    //          "Edit" - Edit mode
    //          "New" - Create new mode
    //"WorkflowID" - ID of the workflow (from SYSTEM_WORKFLOW or -1 if new and TENANT_WORKFLOW if edit)
    //"WorkflowName" - name of the workflow (from SYSTEM_WORKFLOW if new and TENANT_WORKFLOW if edit)
    //"WorkflowDescription" - description of workflow (only for custom add)

    //GridView1.DataSourceID = "SqlDataSource1";
    public partial class WorkflowEdit : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["LoginID"] == null)
                Response.Redirect("UserLogin.aspx");
            else if (Session["WorkflowMode"] == null)
                Response.Redirect("WorkflowManager.aspx");
            else if (lblMode.Text.Length <= 0)
            {
                MiniSaaSDB db = new MiniSaaSDB();
                SqlDataReader reader;
                string loginID = Session["LoginID"].ToString();
                int selectedID = Convert.ToInt32(Session["WorkflowID"].ToString());
                int basedOnID = -1;
                string tenantWorkflowName;
                string tenantWorkflowID;
                db.open();

                if (Session["WorkflowMode"].ToString().Equals("New", StringComparison.CurrentCultureIgnoreCase))
                {
                    lblMode.Text = "Add New Workflow";
                    basedOnID = selectedID;

                    reader = db.executeQuery("SELECT MAX(Tenant_Workflow_ID)+1 FROM TENANT_WORKFLOW");
                    if (!reader.HasRows)
                        tenantWorkflowID = "1";
                    else
                    {
                        reader.Read();
                        if (reader[0].ToString().Length <= 0)
                            tenantWorkflowID = "1";
                        else
                            tenantWorkflowID = reader[0].ToString();
                    }
                    tenantWorkflowName = Session["WorkflowName"].ToString();
                    string command = "INSERT INTO TENANT_WORKFLOW (Tenant_Workflow_ID, Login_ID, " +
                        "Tenant_Workflow_Name, Tenant_Workflow_Description, System_Workflow_ID) VALUES " +
                        "(" + tenantWorkflowID.ToString() + ", " + loginID.ToString() + ", '" + tenantWorkflowName +
                        "', ";
                    if (Session["WorkflowDescription"] == null)
                        command += "NULL, ";
                    else
                        command += "'" + Session["WorkflowDescription"].ToString() + "', ";
                    if (selectedID < 0)
                        command += "NULL);";
                    else
                        command += selectedID.ToString() + ");";
                    db.executeNonQuery(command);
                }
                else
                {
                    lblMode.Text = "Edit Existing Workflow";

                    tenantWorkflowName = Session["WorkflowName"].ToString();
                    tenantWorkflowID = Session["WorkflowID"].ToString();
                }

                //fill table with existing items
                //SqlDataSource1.SelectCommand = "SELECT tws.Order_Number, s.Service_ID, s.Service_Name, s.Service_Path, s.Service_Function_Name, " +
                    //"s.Service_Description FROM SERVICE s INNER JOIN TENANT_WORKFLOW_SERVICE tws ON s.Service_ID = " +
                    //"tws.Service_ID WHERE tws.Tenant_Workflow_ID = " + selectedID.ToString() + " ORDER BY " +
                    //"tws.Order_Number;";
                GridView1.DataBind();

                fillCombo(tenantWorkflowID, db);

                lblWorkflowID.Text = tenantWorkflowID;
                lblWorkflowName.Text = tenantWorkflowName;

                db.close();
            }
        }

        protected void fillCombo(string tenantWorkflowID)
        {
            fillCombo(tenantWorkflowID, null);
        }
        protected void fillCombo(string tenantWorkflowID, MiniSaaSDB db)
        {
            ddlService.Items.Clear();
            bool closeMe = false;
            if (db == null)
            {
                db = new MiniSaaSDB();
                db.open();
                closeMe = true;
            }
            SqlDataReader reader;
            string loginID = Session["LoginID"].ToString();
            int basedOnID;

            reader = db.executeQuery("SELECT System_Workflow_ID FROM TENANT_WORKFLOW WHERE " +
                        "Tenant_Workflow_ID = " + tenantWorkflowID.ToString() + ";");
            if (!reader.HasRows)
                basedOnID = -1;
            else
            {
                reader.Read();
                if (reader[0].ToString().Length <= 0)
                    basedOnID = -1;
                else
                    basedOnID = (int)reader[0];
            }

            //fill the dropdown box with default services
            if (basedOnID >= 0)
            {
                reader = db.executeQuery("SELECT * FROM SERVICE s INNER JOIN SYSTEM_WORKFLOW_SERVICE sws ON " +
                    "s.Service_ID = sws.Service_ID WHERE sws.System_Workflow_ID = " +
                    basedOnID.ToString() + " OR s.Login_ID = " + loginID + ";");
            }
            else
            {
                //Not based on any default workflow - show all default services and services belonging to tenant
                reader = db.executeQuery("SELECT * FROM SERVICE " +
                    "WHERE Login_ID IS NULL" +
                    " OR Login_ID = " + loginID + ";");
                rdoRecommendedYes.Enabled = false;
                rdoRecommendedNo.Enabled = false;
                rdoRecommendedNo.Checked = true;
            }

            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    ddlService.Items.Add(reader["Service_ID"].ToString() + ". " + reader["Service_Function_Name"].ToString());
                    ddlService.Items[ddlService.Items.Count - 1].Value = ddlService.Items[ddlService.Items.Count - 1].Text + "|True";
                }
            }

            if (basedOnID >= 0)
            {
                reader = db.executeQuery("SELECT * FROM SERVICE WHERE Login_ID IS NULL OR Login_ID = " +
                    loginID + " AND Service_ID NOT IN " +
                    "(SELECT s.Service_ID FROM SERVICE s INNER JOIN SYSTEM_WORKFLOW_SERVICE sws ON " +
                    "s.Service_ID = sws.Service_ID WHERE sws.System_Workflow_ID = " +
                    basedOnID.ToString() + " OR s.Login_ID = " + loginID + ");");
                while (reader.Read())
                {
                    ddlService.Items.Add(reader["Service_ID"].ToString() + ". " + reader["Service_Function_Name"].ToString());
                    ddlService.Items[ddlService.Items.Count - 1].Value = ddlService.Items[ddlService.Items.Count - 1].Text+"|False";
                }
            }

            if (ddlService.Items.Count <= 0)
                setCustomEnable(true);
            ddlService.Items.Add("Custom Service:");
            ddlService.Items[ddlService.Items.Count - 1].Value = ddlService.Items[ddlService.Items.Count - 1].Text +"|True";
            refreshRecommended();

            if (closeMe)
                db.close();
        }

        protected void setCustomEnable(bool en)
        {
            txtServiceName.Enabled = en;
            txtServicePath.Enabled = en;
            txtServiceFunction.Enabled = en;
            txtServiceDescription.Enabled = en;
        }

        protected void ddlServices_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ddlService.SelectedIndex == ddlService.Items.Count - 1)
                setCustomEnable(true);
            else
                setCustomEnable(false);
        }

        protected void clearErrors()
        {
            lblErr.Text = "";
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            clearErrors();
            if (ddlService.SelectedIndex == ddlService.Items.Count - 1 &&
                (txtServiceName.Text.Length <= 0 || txtServiceName.Text.Length <= 0 ||
                txtServiceFunction.Text.Length <= 0))
            {
                lblErr.Text = "Please fill out custom fields";
                return;
            }

            MiniSaaSDB db = new MiniSaaSDB();
            SqlDataReader reader;
            db.open();
            int serviceID;
            int nextOrderNumber;

            if (ddlService.SelectedIndex == ddlService.Items.Count - 1)
            {
                //add service to db
                reader = db.executeQuery("SELECT MAX(Service_ID)+1 FROM SERVICE");
                if (!reader.HasRows)
                    serviceID = 1;
                else
                {
                    reader.Read();
                    if (reader[0].ToString().Length <= 0)
                        serviceID = 1;
                    else
                        serviceID = (int)reader[0];
                }
                db.executeQuery("INSERT INTO SERVICE (Service_ID, Service_Name, " +
                "Service_Path, Service_Function_Name, Service_Description, Login_ID) VALUES (" + serviceID.ToString() +
                ", '" + txtServiceName.Text.Trim() + "', '" + txtServicePath.Text.Trim() + "', '" +
                txtServiceFunction.Text.Trim() + "', '" + txtServiceDescription.Text.Trim() + "', " +
                Session["LoginID"] + ");");
            }
            else
            {
                serviceID = Convert.ToInt32(ddlService.Text.Substring(0, ddlService.Text.IndexOf('.')));
            }
            reader = db.executeQuery("SELECT MAX(Order_Number)+1 FROM TENANT_WORKFLOW_SERVICE WHERE " +
                "Tenant_Workflow_ID = " + lblWorkflowID.Text + ";");
            if (!reader.HasRows)
                nextOrderNumber = 1;
            else
            {
                reader.Read();
                if (reader[0].ToString().Length <= 0)
                    nextOrderNumber = 1;
                else
                    nextOrderNumber = (int)reader[0];
            }
            string nextID;
            reader = db.executeQuery("SELECT MAX(Tenant_Workflow_Service_ID)+1 FROM TENANT_WORKFLOW_SERVICE");
            if (!reader.HasRows)
            {
                nextID = "1";
            }
            else
            {
                reader.Read();
                if (reader[0] == null || reader[0].ToString().Equals(""))
                    nextID = "1";
                else
                    nextID = reader[0].ToString();
            }
            db.executeNonQuery("INSERT INTO TENANT_WORKFLOW_SERVICE (Tenant_Workflow_Service_ID, Tenant_Workflow_ID, Order_Number, Service_ID) " +
                "VALUES ("+ nextID + ", " + lblWorkflowID.Text + ", " + nextOrderNumber.ToString() + ", " + serviceID.ToString() + ");");
            GridView1.DataBind();
            db.close();
        }

        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Del")
            {
                // Retrieve the row index stored in the 
                // CommandArgument property.
                int index = Convert.ToInt32(e.CommandArgument);
                string orderNumber = GridView1.Rows[index].Cells[0].Text;
                string tenantWorkflowID = lblWorkflowID.Text;
                MiniSaaSDB db = new MiniSaaSDB();
                db.open();
                db.executeNonQuery("DELETE FROM TENANT_WORKFLOW_SERVICE WHERE Tenant_Workflow_ID = " + tenantWorkflowID +
                    " AND Order_Number = " + orderNumber + ";");
                db.close();
                GridView1.DataBind();
            }
            else
            {
                int index = Convert.ToInt32(e.CommandArgument);
                int selectedOrder = Convert.ToInt32(GridView1.Rows[index].Cells[0].Text);
                string command = "UPDATE TENANT_WORKFLOW_SERVICE SET Order_Number = -1 WHERE Tenant_Workflow_ID = "
                    + lblWorkflowID.Text + " AND Order_Number = " + selectedOrder.ToString() + "; ";
                MiniSaaSDB db = new MiniSaaSDB();
                if (e.CommandName == "moveUp")
                {
                    if (index <= 0)
                        return;
                    db.open();
                    command += "UPDATE TENANT_WORKFLOW_SERVICE SET Order_Number = " + selectedOrder.ToString() + " WHERE Tenant_Workflow_ID = "
                    + lblWorkflowID.Text + " AND Order_Number = " + GridView1.Rows[index - 1].Cells[0].Text + "; ";
                    command += "UPDATE TENANT_WORKFLOW_SERVICE SET Order_Number = " + GridView1.Rows[index - 1].Cells[0].Text + " WHERE Tenant_Workflow_ID = "
                    + lblWorkflowID.Text + " AND Order_Number = -1; ";
                    db.executeNonQuery(command);
                    db.close();
                }
                else if (e.CommandName == "moveDown")
                {
                    if (index >= GridView1.Rows.Count)
                        return;
                    db.open();
                    command += "UPDATE TENANT_WORKFLOW_SERVICE SET Order_Number = " + selectedOrder.ToString() + " WHERE Tenant_Workflow_ID = "
                    + lblWorkflowID.Text + " AND Order_Number = " + GridView1.Rows[index + 1].Cells[0].Text + "; ";
                    command += "UPDATE TENANT_WORKFLOW_SERVICE SET Order_Number = " + GridView1.Rows[index + 1].Cells[0].Text + " WHERE Tenant_Workflow_ID = "
                    + lblWorkflowID.Text + " AND Order_Number = -1; ";
                    db.executeNonQuery(command);
                    db.close();
                }
                GridView1.DataBind();
            }
        }

        protected void Button2_Click(object sender, EventArgs e)
        {
            update();
        }

        protected void update()
        {
            clearErrors();
            fillCombo(lblWorkflowID.Text);
            string searchValue = txtSearch.Text.Trim();
            if (searchValue.Equals("") || searchValue.Equals("*"))
                return;
            List<string> output;
            List<string> values = new List<string>();
            List<string> listItems = new List<string>();
            string itemID;
            int matchingID;
            SaaS.searchKeywords sKeywords = new SaaS.searchKeywords();

            // return a string list with score larger than threshold, 
            // sorted by the score, the first one has the largest score
            output = sKeywords.findKeywords(searchValue, 0.3);

            //find services
            SaaS.searchOntology sOntology = new SaaS.searchOntology();
            if (output.Count > 0)
            {
                HashSet<string> serviceIdList = sOntology.findService(output);
                string display = "";
                string str;
                for (int i = 0; i < serviceIdList.Count; i++)
                {
                    str = serviceIdList.ElementAt(i);
                    matchingID = -1;
                    //display = display + "  " + str;
                    for (int j = 0; j < ddlService.Items.Count - 1; j++)
                    {
                        itemID = ddlService.Items[j].Text.Substring(0, ddlService.Items[j].Text.IndexOf('.'));
                        if (itemID.Equals(str))
                        {
                            matchingID = j;
                            break;
                        }
                    }
                    if (matchingID >= 0)
                    {
                        listItems.Add(ddlService.Items[matchingID].Text);
                        values.Add(ddlService.Items[matchingID].Value);
                    }
                }
                //Label_serviceID.Text = "service id found:  " + display;
            }
            ddlService.Items.Clear();
            for (int i = 0; i < listItems.Count; i++)
            {
                ddlService.Items.Add(listItems[i]);
                ddlService.Items[i].Value = values[i];
            }

            if (ddlService.Items.Count <= 0)
                setCustomEnable(true);
            ddlService.Items.Add("Custom Service:");
            ddlService.Items[ddlService.Items.Count - 1].Value = ddlService.Items[ddlService.Items.Count - 1].Text + "|True";
            refreshRecommended();
        }

        protected void rdoRecommendedYes_CheckedChanged(object sender, EventArgs e)
        {
            refreshRecommended();
        }

        protected void rdoRecommendedNo_CheckedChanged(object sender, EventArgs e)
        {
            refreshRecommended();
        }

        protected void refreshRecommended()
        {
            bool s = rdoRecommendedNo.Checked;
            int enableCount = 0;
            int firstBreak;
            int secondBreak;
            string value;
            for (int i = 0; i < ddlService.Items.Count; i++)
            {
                firstBreak = ddlService.Items[i].Value.IndexOf('|');
                if (firstBreak < 0)
                {
                    firstBreak = 0;
                    secondBreak = ddlService.Items[i].Value.Length;
                }
                else
                {
                    firstBreak++;
                    secondBreak = ddlService.Items[i].Value.IndexOf('|',firstBreak);
                    if (secondBreak < 0)
                        secondBreak = ddlService.Items[i].Value.Length-1;
                    else
                        secondBreak--;
                }

                value = ddlService.Items[i].Value.Substring(firstBreak, secondBreak - firstBreak + 1);
                if (value.Equals("False"))
                    ddlService.Items[i].Enabled = s;
                else
                {
                    ddlService.Items[i].Enabled = true;
                    enableCount++;
                }
            }
            if (enableCount <= 1)
                setCustomEnable(true);
            ddlService_SelectedIndexChanged1(null, null);
        }

        protected void txtServiceFunc_TextChanged(object sender, EventArgs e)
        {

        }

        protected void txtServiceDesc_TextChanged(object sender, EventArgs e)
        {

        }

        protected void Button3_Click(object sender, EventArgs e)
        {
            txtSearch.Text = "";
            update();
        }

        protected void ddlService_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        protected void ddlService_SelectedIndexChanged1(object sender, EventArgs e)
        {
            if (ddlService.SelectedIndex == ddlService.Items.Count - 1)
            {
                setCustomEnable(true);
                txtServiceDescription.Text = "";
                txtServiceFunction.Text = "";
                txtServiceName.Text = "";
                txtServicePath.Text = "";
            }
            else
            {
                setCustomEnable(false);
                string serviceID;
                serviceID = ddlService.Text.Substring(0, ddlService.Text.IndexOf('.'));
                MiniSaaSDB db = new MiniSaaSDB();
                db.open();
                SqlDataReader reader;
                reader = db.executeQuery("SELECT * FROM SERVICE WHERE Service_ID = " + serviceID + ";");
                if (!reader.HasRows)
                {
                    txtServiceDescription.Text = "";
                    txtServiceFunction.Text = "";
                    txtServiceName.Text = "";
                    txtServicePath.Text = "";
                }
                else
                {
                    reader.Read();
                    txtServiceDescription.Text = reader["Service_Description"].ToString();
                    txtServiceFunction.Text = reader["Service_Function_Name"].ToString();
                    txtServiceName.Text = reader["Service_Name"].ToString();
                    txtServicePath.Text = reader["Service_Path"].ToString();
                }
                db.close();
            }
        }

        protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
